/**
 * <pre>
 * Title: 		TopService.java
 * Project: 	TopService
 * Type:		com.leoly.TopService
 * Author:		255507
 * Create:	 	2013-1-8 下午6:37:44
 * Copyright: 	Copyright (c) 2013
 * Company:		
 * <pre>
 */
package com.leoly.fullnexus4.services;

import java.util.List;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

import com.leoly.fullnexus4.R;
import com.leoly.fullnexus4.utils.ButtonFactory;
import com.leoly.fullnexus4.utils.TopConstants;
import com.leoly.fullnexus4.views.ExtraImageView;
import com.leoly.fullnexus4.views.ExtraScrollView;
import com.leoly.fullnexus4.views.IScrollView;

import android.util.Log;

/**
 * <pre>
 * </pre>
 * @author 255507
 * @version 1.0, 2013-1-8
 */
public class FullNexus4Service extends Service
{

	private WindowManager wm;

	private LinearLayout layout;

	private WindowManager.LayoutParams params = null;

	private Context context;

	private ImageView tab;

	// 按键区当前状态是显示还是隐藏
	private boolean isShow = false;

	// 按键区位置
	private int keyLocation = TopConstants.BUTTOM;

	// 按键区的高度,在左边和右边时为宽度
	private int keyHeight = 96;

	// 按键区隐藏时间
	private int hideTime = 5;

	// Button size
	private int btnSize = 72;

	// 按键区域透明度
	private int keyAlpha = 123;

	// 按键区域背景色
	private int keysetColor = Color.BLACK;
	
	// Drag to trigger menu
	private float dragThreshold = 50;
	private float dragStartY = 0;
	private boolean isDragging = false;

	private Handler handler = new Handler()
	{
		@Override
		public void handleMessage(Message msg)
		{
			Bundle data = msg.getData();
			boolean wantShow = data.getBoolean(TopConstants.HANDLER_TAG);
			if (wantShow)
			{
				if (isShow)
				{
					hideKeys();
				}
				else
				{
					showKeys();
				}
			}
		}
	};

	private Runnable run = new Runnable()
	{
		public void run()
		{
			Bundle bundle = new Bundle();
			bundle.putBoolean(TopConstants.HANDLER_TAG, true);
			Message msg = new Message();
			msg.setData(bundle);
			handler.sendMessage(msg);
		}
	};

	/*
	 * （非 Javadoc）
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	@Override
	public IBinder onBind(Intent arg0)
	{
		return null;
	}

	@Override
	public void onCreate()
	{
		context = getApplicationContext();

		// 顶级窗口配置
		wm = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
		params = new WindowManager.LayoutParams();
		// 关键属性
		params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
		params.format = 1;
		params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
		params.flags = params.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
		params.flags = params.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
		isShow = true;

		// 屏幕大小
		Display display = wm.getDefaultDisplay();
		// 加载Layout
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
		// 加载配置项
		SharedPreferences prefer = getSharedPreferences(TopConstants.CONFIG_NAME, MODE_PRIVATE);
		
		// MAKOTO: Force settings to test the functions of each param
		keyLocation = TopConstants.BUTTOM;
		String customKeys = null;
		// 设置自动隐藏时间
		hideTime = prefer.getInt(TopConstants.HIDE_TIME, 5);
		
		keyHeight = prefer.getInt(TopConstants.KEY_SET_HEIGHT, 10);
		keyHeight = ButtonFactory.getRealValue(keyHeight, 1);
		
		keyAlpha = prefer.getInt(TopConstants.KEY_SET_ALPHA, 123);
		keysetColor = prefer.getInt(TopConstants.KEY_SET_COLOR, Color.BLACK);
		 
		// 根据按键配置获取真实的按钮
		ButtonFactory facotry = ButtonFactory.getInstance(context, keyLocation, new ICallBack()
		{
			public void run()
			{
				handler.removeCallbacks(run);
				handler.postDelayed(run, hideTime * 1000);
			}
		});
		List<ExtraImageView> btns = facotry.getButtons(customKeys);

		// Button bar total width should be same as screen width
		int totalWidth = display.getWidth();
		
		// Margin for normal button
		// Margin on width is different for every button
		int btnMarginY = (int)((keyHeight - btnSize) / 2);
		
		int btnMarginL = 0;
		int btnMarginR = 0;

		switch (keyLocation)
		{
			case TopConstants.BUTTOM:
				params.width = totalWidth;
				params.height = keyHeight;
				params.y = 0;
				params.gravity = Gravity.BOTTOM;
				layout = (LinearLayout) inflater.inflate(R.layout.main, null);
				LinearLayout btnLayout = (LinearLayout) layout.findViewById(R.id.btnsLayout);
				for (ExtraImageView iv : btns)
				{
					LayoutParams btnParam = new LayoutParams(btnSize, btnSize);
					
					switch( iv.getID() ){
						case ButtonFactory.BACK:
							btnMarginL = 124;
							break;
						case ButtonFactory.HOME:
							btnMarginL = 152;
							break;
						case ButtonFactory.RECENT:
							btnMarginL = 156;
							break;
						case ButtonFactory.MENU:
							btnMarginL = 48;
							break;
						default:
							// WTF!
							break;
					}
					
					btnParam.setMargins(btnMarginL, btnMarginY, btnMarginR, btnMarginY);
					btnLayout.addView(iv, btnLayout.getChildCount(), btnParam);
				}
				break;
			default:
				break;
		}

		layout.setOnTouchListener(new OnTouchListener()
		{
			public boolean onTouch(View arg0, MotionEvent event)
			{
				if (event.getAction() == MotionEvent.ACTION_OUTSIDE)
				{
					hideKeys();
				}

				return false;
			}
		});
		
		// Drag area to trigger menu
		tab = (ImageView) layout.findViewById(R.id.tabPanel);
		tab.setOnTouchListener(new OnTouchListener()
		{
			public boolean onTouch(View arg0, MotionEvent event)
			{
				int key = event.getAction();
				if (key == MotionEvent.ACTION_DOWN)
				{
					dragStartY = event.getRawY();
					isDragging = true;
				}
				if (key == MotionEvent.ACTION_UP)
				{
					float dragNowY = event.getRawY();
					if( isDragging && ( dragStartY - dragNowY ) > dragThreshold )
					{
						showKeys();
					}					
				}
				return true;
			}
		});

		IScrollView esv = (IScrollView) layout.findViewById(R.id.extraScrollView);
		esv.setCallback(new ICallBack()
		{
			public void run()
			{
				handleTab(TopConstants.REMOVE_AND_POST);
			}
		});

		esv.setColor(ButtonFactory.getRealColor(keysetColor));
		esv.setBackgroundAlpha(keyAlpha);
		
		wm.addView(layout, params);
		handleTab(TopConstants.POST);
	}

	private void hideKeys()
	{
		if (!isShow)
		{
			return;
		}
		switch (keyLocation)
		{
			case TopConstants.BUTTOM:
				params.y = -(keyHeight - 25);
				break;
			case TopConstants.LEFT:
				params.x = -(keyHeight - 25);
				break;
			case TopConstants.RIGHT:
				params.x = -(keyHeight - 25);
				break;
			default:
				break;
		}

		wm.updateViewLayout(layout, params);
		isShow = false;
		handleTab(TopConstants.REMOVE);
	}

	private void showKeys()
	{
		if (isShow)
		{
			return;
		}
		switch (keyLocation)
		{
			case TopConstants.BUTTOM:
				params.y = 0;
				break;
			case TopConstants.LEFT:
				params.x = 0;
				break;
			case TopConstants.RIGHT:
				params.x = 0;
				break;
			default:
				break;
		}

		wm.updateViewLayout(layout, params);
		isShow = true;
		handleTab(TopConstants.POST);
	}

	private void handleTab(int type)
	{
		if (hideTime > 0)
		{
			switch (type)
			{
				case TopConstants.POST:
					handler.postDelayed(run, hideTime * 1000);
					break;
				case TopConstants.REMOVE:
					handler.removeCallbacks(run);
					break;
				case TopConstants.REMOVE_AND_POST:
					handler.removeCallbacks(run);
					handler.postDelayed(run, hideTime * 1000);
					break;
				default:
					break;
			}
		}
	}

	@Override
	public void onDestroy()
	{
		super.onDestroy();
		wm.removeViewImmediate(layout);
		handleTab(TopConstants.REMOVE);
		stopSelf();
	}

	@Override
	public void onTaskRemoved(Intent rootIntent)
	{
		super.onTaskRemoved(rootIntent);
	}
}
